﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Drawing.Win32;

namespace HoldemHook
{
	#region EnumWindows
	/// <summary>
	/// EnumWindows wrapper for .NET
	/// </summary>
	public class EnumWindows
	{
		#region Delegates
        public delegate bool EnumWndDelegate(IntPtr hWnd);
		#endregion

		#region UnManagedMethods
		private class UnManagedMethods
		{
			[DllImport("user32")]
			public extern static int EnumWindows (
				Api.EnumWindowsProc lpEnumFunc, 
				int lParam);
			[DllImport("user32")]
			public extern static int EnumChildWindows (
				IntPtr hWndParent,
                Api.EnumWindowsProc lpEnumFunc, 
				int lParam);
		}
		#endregion

		#region Member Variables
		private EnumWindowsCollection items = null;
		#endregion

        public EnumWndDelegate EnumWnd = null;

		/// <summary>
		/// Returns the collection of windows returned by
		/// GetWindows
		/// </summary>
		public EnumWindowsCollection Items
		{
			get
			{
				return this.items;
			}
		}

		/// <summary>
		/// Gets all top level windows on the system.
		/// </summary>
		public void GetWindows()
		{
			this.items = new EnumWindowsCollection();
			UnManagedMethods.EnumWindows(
                new Api.EnumWindowsProc(this.WindowEnum),
				0);
		}
		/// <summary>
		/// Gets all child windows of the specified window
		/// </summary>
		/// <param name="hWndParent">Window Handle to get children for</param>
		public void GetWindows(
			IntPtr hWndParent)
		{
			this.items = new EnumWindowsCollection();
			UnManagedMethods.EnumChildWindows(
				hWndParent,
                new Api.EnumWindowsProc(this.WindowEnum),
				0);
		}

		#region EnumWindows callback
		/// <summary>
		/// The enum Windows callback.
		/// </summary>
		/// <param name="hWnd">Window Handle</param>
		/// <param name="lParam">Application defined value</param>
		/// <returns>1 to continue enumeration, 0 to stop</returns>
		private int WindowEnum(
			IntPtr hWnd,
			int lParam)
		{
            if (this.EnumWnd != null)
                return this.EnumWnd(hWnd) ? 1:0;
            else return this.OnWindowEnum(hWnd) ? 1:0;
		}
		#endregion

		/// <summary>
		/// Called whenever a new window is about to be added
		/// by the Window enumeration called from GetWindows.
		/// If overriding this function, return true to continue
		/// enumeration or false to stop.  If you do not call
		/// the base implementation the Items collection will
		/// be empty.
		/// </summary>
		/// <param name="hWnd">Window handle to add</param>
		/// <returns>True to continue enumeration, False to stop</returns>
		protected virtual bool OnWindowEnum(
			IntPtr hWnd)
		{
			items.Add(new WinWnd(hWnd));
			return true;
		}

		#region Constructor, Dispose
		public EnumWindows()
		{
			// nothing to do
		}
		#endregion
	}	
	#endregion EnumWindows

	#region EnumWindowsCollection
	/// <summary>
	/// Holds a collection of Windows returned by GetWindows.
	/// </summary>
    [Serializable]
	public class EnumWindowsCollection : ReadOnlyCollectionBase
	{
		/// <summary>
		/// Add a new Window to the collection.  Intended for
		/// internal use by EnumWindows only.
		/// </summary>
		/// <param name="hWnd">Window handle to add</param>
		public void Add(WinWnd wnd)
		{
			this.InnerList.Add(wnd);
		}

		/// <summary>
		/// Gets the Window at the specified index
		/// </summary>
		public WinWnd this[int index]
		{
			get
			{
				return (WinWnd)this.InnerList[index];
			}
		}

		/// <summary>
		/// Constructs a new EnumWindowsCollection object.
		/// </summary>
		public EnumWindowsCollection()
		{
			// nothing to do
		}
	}
	#endregion		

    
  
}

